<template>
  <div class="users">
    <!-- 八 头部面包屑 -->
    <el-breadcrumb separator="/">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>
        <a href="/">用户管理</a>
      </el-breadcrumb-item>
      <el-breadcrumb-item>用户列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 八 搜索功能 -->
    <div>
      <!--八 1.1 v-model双向数据绑定 用来获取输入框的值 用作我query的值 -->
      <el-input placeholder="请输入内容" v-model="searchUser" class="input-with-select search-input">
        <!-- 八 1.3 点击执行查询函数 -->
        <el-button slot="append" icon="el-icon-search" @click="handleSearch"></el-button>
      </el-input>
      <el-button type="primary" plain @click="handleAdd">添加用户</el-button>
    </div>
    <!-- v-loading自定义指令用来实现页面有加载动画的效果 -->
    <el-table :data="tableData" border style="width: 100%" class="mt-15 mb-15" v-loading="loading">
      <el-table-column type="index" width="50"></el-table-column>
      <el-table-column prop="username" label="姓名" width="180"></el-table-column>
      <el-table-column prop="email" label="邮箱" width="180"></el-table-column>
      <el-table-column prop="mobile" label="电话"></el-table-column>
      <el-table-column prop="mg_state" label="状态">
        <template slot-scope="scope">
          <!--八 6.0 通过作用域插槽 我们展示状态按按钮的组件 通过scope.rpw.mg_state来动态获取每一个用户的状态 -->
          <el-switch
            @change="handlestate(scope.row)"
            v-model="scope.row.mg_state"
            active-color="#13ce66"
            inactive-color="#c1c1c1"
          ></el-switch>
        </template>
      </el-table-column>
      <el-table-column prop label="操作">
        <!-- 使用作用域插槽 -->
        <template slot-scope="scope">
          <!--  @click="handleEdit(scope.row)"  scope.row保存的是当前点击的用户信息-->
          <el-button
            size="mini"
            type="primary"
            icon="el-icon-edit"
            @click="handleEdit(scope.row)"
            circle
          ></el-button>
          <el-button
            size="mini"
            type="danger"
            icon="el-icon-delete"
            circle
            @click="handleDelete(scope.row)"
          ></el-button>
          <el-button
            size="mini"
            type="success"
            icon="el-icon-check"
            circle
            @click="handleCheck(scope.row)"
          ></el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页功能 -->
    <el-pagination
      class="page"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="currentPage4"
      :page-sizes="[10, 20, 30, 40]"
      :page-size="10"
      layout="total, sizes, prev, pager, next, jumper"
      :total="pageTotal"
    ></el-pagination>
    <!--八 2.1 添加用户的静态制作 -->
    <!-- 八3.1 @close用来监听我们添加用户的时候 但是我们又不想操作 会点击x关闭或者取消 我们要将表格的内容都清空掉 -->
    <el-dialog title="添加用户" :visible.sync="addDialogFormVisible" @close="closeTable">
      <el-form :model="addForm" :rules="addRules" ref="addRef">
        <el-form-item label="姓名" label-width="90px" prop="username">
          <el-input v-model="addForm.username" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="密码" label-width="90px" prop="password">
          <el-input v-model="addForm.password" autocomplete="off" type="password"></el-input>
        </el-form-item>
        <el-form-item label="邮箱" label-width="90px" prop="email">
          <el-input v-model="addForm.email" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="电话" label-width="90px" prop="mobile">
          <el-input v-model="addForm.mobile" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addDialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="isAdd">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 编辑用户 的弹窗 -->
    <el-dialog title="编辑用户" :visible.sync="editDialogFormVisible">
      <el-form :model="editForm" :rules="addRules" ref="editRef">
        <el-form-item label="姓名" label-width="90px">
          <el-input v-model="editForm.username" autocomplete="off" disabled></el-input>
        </el-form-item>
        <el-form-item label="邮箱" label-width="90px" prop="email">
          <el-input v-model="editForm.email" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="电话" label-width="90px" prop="mobile">
          <el-input v-model="editForm.mobile" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editDialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="isEdit">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 分配角色 的弹窗 -->
    <el-dialog title="分配角色" :visible.sync="checkDialogFormVisible">
      <el-form :model="checkForm">
        <el-form-item label="用户名称" label-width="90px">
          <el-tag type="warning">{{checkForm.username}}</el-tag>
        </el-form-item>
        <el-form-item label="角色选择" label-width="90px">
          <!-- 九 1.3 element组件实现角色选择器 -->
          <el-select v-model="selectRoleId" placeholder="请选择">
            <!-- label属性用来设置显示文字的字段 -->
            <!-- value 属性是用来标记我当前选择显示的是哪一个的文字字段 -->
            <el-option
              v-for="item in selectRoles"
              :key="item.id"
              :label="item.roleName"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="checkDialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="isCheck">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {
  getUsersData,
  addUser,
  delUser,
  editUser,
  userState,
  grantCheckRole,
  checkRoleOk
} from '@/api'
export default {
  data () {
    // 八 3.1自定义邮箱校验规则
    let Email = (rule, value, cb) => {
      // 当没有输入值的时候
      if (value === '') {
        // 回调一个信息给validator属性 通过new Error（）
        cb(new Error('请输入邮箱'))
      } else {
        // 当有输入的时候 通过正则判断输入是否正确
        let emailReg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
        if (emailReg.test(value)) {
          // 正确直接回调
          cb()
        } else {
          // 没有输入正确格式的信息回调
          cb(new Error('请输入正确的邮箱格式'))
        }
      }
    }
    return {
      searchUser: '', // 搜索数据
      tableData: [], // 表格数据
      currentPage4: 4,
      addDialogFormVisible: false, // 八 2.3切换添加用户的显示
      editDialogFormVisible: false, // 八 5.1切换编辑用户的列表
      checkDialogFormVisible: false, // 九 1.0 切换分配角色框
      pageTotal: 0, // 在分页处显示数据的总条数
      pagenum: 1, // 所在的哪一页
      pagesize: 10, // 数据的条数
      loading: true, // 加载效果的组件
      addForm: {
        username: '',
        password: '',
        email: '',
        mobile: ''
      },
      editForm: {
        username: '',
        email: '',
        mobile: '',
        id: ''
      },
      checkForm: {
        username: '',
        uid: ''
      },
      // 九 1.4角色选择项
      selectRoles: [],
      selectRoleId: '',
      addRules: {
        username: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
        password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
        // 八 3.2通过validator获取自定邮箱规则 cb的值
        email: [
          { required: true, validator: Email, trigger: ['blur', 'change'] }
        ],
        mobile: [{ required: true, message: '请输入电话', trigger: 'blur' }]
      }
    }
  },
  created () {
    this.renderUser()
  },
  methods: {
    // 八 请求用户的数据 渲染到信息栏
    renderUser () {
      this.loading = true
      // 八 1.2 将query的值变为一个双向数据绑定的变量 query是查询参数
      getUsersData({
        query: this.searchUser,
        pagenum: this.pagenum,
        pagesize: this.pagesize
      }).then(res => {
        //   console.log(res)
        this.tableData = res.data.data.users
        this.pageTotal = res.data.data.total
        this.loading = false
      })
    },
    // 八 2.2添加用户
    handleAdd () {
      this.addDialogFormVisible = true
    },
    // 八 2.3 确认添加用户
    isAdd () {
      // 验证填写的用户信息
      this.$refs.addRef.validate(isTrue => {
        if (isTrue) {
          addUser({
            username: this.addForm.username,
            password: this.addForm.password,
            email: this.addForm.email,
            mobile: this.addForm.mobile
          }).then(res => {
            console.log(res)
            if (res.data.meta.status === 201) {
              // 成功添加的提示信息
              this.$message.success(res.data.meta.msg)
              this.renderUser()
              this.addDialogFormVisible = false
              this.addForm.username = ''
              this.addForm.password = ''
              this.addForm.email = ''
              this.addForm.mobile = ''
            } else {
              this.$message.error(res.data.meta.msg)
            }
          })
        } else {
          console.log('no')
        }
      })
    },
    // 八 3.2 关闭或者取消执行的逻辑 清空表格数据
    closeTable () {
      // 清空表格数据 使用resetFields清空表格  $refs获取dom元素
      this.$refs.addRef.resetFields()
      //   this.$refs.addRef.clearValidate()
    },
    // 八 4.1删除用户的逻辑函数
    handleDelete (row) {
      // 我们应该在删除之前 弹框询问我们是否真的删除 而不是直接删除
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        // 点击确定执行的函数
        .then(() => {
          // row里面有我们需要的当前点击的用户的id
          //   console.log(row.id)
          delUser(row.id).then(res => {
            console.log(res)
            if (res.data.meta.status === 200) {
              this.$message.success(res.data.meta.msg)
              this.renderUser()
            } else {
              this.$message.error(res.data.meta.msg)
            }
          })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
    },
    // 八 5.2点击编辑 icon的时候 编辑的处理逻辑
    handleEdit (row) {
      console.log(row)
      this.editDialogFormVisible = true
      this.editForm.id = row.id
      this.editForm.username = row.username
      this.editForm.email = row.email
      this.editForm.mobile = row.mobile
    },
    // 八 5.3 点击确定编辑 发送请求
    isEdit () {
      editUser(this.editForm).then(res => {
        if (res.data.meta.status === 200) {
          this.$message.success(res.data.meta.msg)
          this.renderUser()
          this.editDialogFormVisible = false
        } else {
          this.$message.error(res.data.meta.msg)
        }
      })
    },
    // 八 6.1 切换状态函数的逻辑
    handlestate (row) {
      userState(row.id, row.mg_state).then(res => {
        if (res.data.meta.status === 200) {
          // console.log(res)
          this.$message.success(res.data.meta.msg)
          this.renderUser() // 刷新表格数据
        } else {
          this.$message.error(res.data.meta.msg)
        }
      })
    },
    handleSearch () {
      this.renderUser()
    },
    // 八 7.1获取分页条数 赋值给我的数据模型的pagesize 再重新发请求
    handleSizeChange (val) {
      //   console.log(`每页 ${val} 条`)
      this.pagesize = val
      this.renderUser()
    },
    // 八 7.2获取当前所在哪一页 赋值再重新请求数据
    handleCurrentChange (val) {
      console.log(`当前页: ${val}`)
      this.pagenum = val // val保存的是我当前在哪一页
      this.renderUser() //
    },
    // 九 1.1分配角色的确定键的处理函数
    isCheck () {
      // 我们selectRoleId一开始为了保存的是角色id 但是为了解决bug我们使用它获取了字符串 加入我们没有进行选项选择 就不需要请求数据 所以我们在请求之前判断我们当前的操作有没有进行选项 没有就不请求
      if (typeof this.selectRoleId === 'string') {
        this.checkDialogFormVisible = false
        return false
      }
      checkRoleOk(this.checkForm.uid, this.selectRoleId)
        .then(res => {
          if (res.data.meta.status === 200) {
            this.$message.success(res.data.meta.msg)
            this.checkDialogFormVisible = false
            this.renderUser()
          }
        })
    },
    // 九 1.2切换显示 隐藏 分配角色框
    handleCheck (row) {
      console.log(row)
      this.checkDialogFormVisible = true
      this.checkForm.uid = row.id
      // 获取当前分配角色的用户名
      this.checkForm.username = row.username
      // 为了解决我们点击确定了角色后 避免再次点击查看时大家都显示同一个角色我们需要在我们点击查看的时候 将我们请求道的数据的roleName通过双向数据绑定 显示在我们的option先 让大家看到每个角色不同的角色名（bug）
      this.selectRoleId = row.role_name
      // 请求角色列表
      grantCheckRole().then(res => {
        console.log(res)
        if (res.data.meta.status === 200) {
          this.selectRoles = res.data.data
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.search-input {
  width: 300px;
  margin-right: 15px;
}
</style>
